001    /*
002     * Copyright 2004-2005 Stephen McConnell
003     *
004     * Licensed  under the  Apache License,  Version 2.0  (the "License");
005     * you may not use  this file  except in  compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *   http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed  under the  License is distributed on an "AS IS" BASIS,
012     * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
013     * implied.
014     *
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    
019    package net.dpml.tools.tasks;
020    
021    import java.io.File;
022    
023    import net.dpml.library.Resource;
024    import net.dpml.library.info.Scope;
025    
026    import net.dpml.tools.Context;
027    
028    import org.apache.tools.ant.BuildException;
029    import org.apache.tools.ant.Project;
030    import org.apache.tools.ant.taskdefs.Copy;
031    import org.apache.tools.ant.taskdefs.Javac;
032    import org.apache.tools.ant.taskdefs.Mkdir;
033    import org.apache.tools.ant.taskdefs.MatchingTask;
034    import org.apache.tools.ant.types.FileSet;
035    import org.apache.tools.ant.types.Path;
036    
037    /**
038     * Compile sources located in ${project.target}/main to java class file under
039     * the ${project.target}/classes directory.  Properties influencing the compilation
040     * include:
041     * <ul>
042     *  <li>project.javac.debug : boolean true (default) or false</li>
043     *  <li>project.javac.fork: boolean true or false (default) </li>
044     *  <li>project.javac.deprecation: boolean true (default) or false</li>
045     * </ul>
046     * @author <a href="http://www.dpml.net">The Digital Product Meta Library</a>
047     * @version 1.0.0
048     */
049    public class JavacTask extends MatchingTask
050    {
051       /**
052        * Constant debug key.
053        */ 
054        public static final String DEBUG_KEY = "project.javac.debug";
055    
056       /**
057        * Constant fork key.
058        */ 
059        public static final String FORK_KEY = "project.javac.fork";
060    
061       /**
062        * Constant deprecation warning key.
063        */ 
064        public static final String DEPRECATION_KEY = "project.javac.deprecation";
065    
066       /**
067        * Constant src directory key.
068        */ 
069        public static final String SOURCE_KEY = "project.javac.source";
070    
071       /**
072        * Constant classes target directory key.
073        */ 
074        public static final String TARGET_KEY = "project.javac.target";
075    
076        private static final boolean DEBUG_VALUE = true;
077        private static final boolean FORK_VALUE = false;
078        private static final boolean DEPRECATION_VALUE = true;
079        private static final String SOURCE_VALUE = "1.4";
080        private static final String TARGET_VALUE = "1.4";
081    
082        private final Context m_context;
083        
084        private String m_classPathRef;
085        private Path m_classPath;
086        private File m_destination;
087        private File m_source;
088       
089       /**
090        * Creation of a new JavacTask.
091        * @param context the project context
092        */
093        public JavacTask( Context context )
094        {
095            super();
096            m_context = context;
097            try
098            {
099                Resource resource = context.getResource();
100                setProject( context.getProject() );
101                setTaskName( "javac" );
102                setSrc( context.getTargetBuildMainDirectory() );
103                setDest( context.getTargetClassesMainDirectory() );
104                context.getPath( Scope.RUNTIME );
105                setClasspathRef( "project.compile.path" );
106            }
107            catch( Exception e )
108            {
109                throw new BuildException( e );
110            }
111        }
112        
113       /**
114        * Set the compilation classpath.
115        * @param path the classpath
116        */
117        public void setClasspath( Path path ) 
118        {
119            m_classPath = path;
120        }
121        
122       /**
123        * Set the id of the compilation classpath.
124        * @param id the classpath reference
125        */
126        public void setClasspathRef( String id ) 
127        {
128            m_classPathRef = id;
129        }
130        
131       /**
132        * Set the destination directory.
133        * @param destination the destination directory
134        */
135        public void setDest( File destination )
136        {
137            m_destination = destination;
138        }
139        
140       /**
141        * Set the src directory.
142        * @param source the src directory
143        */
144        public void setSrc( File source )
145        {
146            m_source = source;
147        }
148        
149       /**
150        * Task execution.
151        */
152        public void execute()
153        {
154            if( null == m_destination )
155            {
156                final String error = 
157                  "Missing 'dest' attribute.";
158                throw new BuildException( error, getLocation() );
159            }
160            if( null == m_source )
161            {
162                final String error = 
163                  "Missing 'src' attribute.";
164                throw new BuildException( error, getLocation() );
165            }
166            
167            if( !m_source.exists() )
168            {
169                return;
170            }
171            
172            final Path classpath = getClasspath();
173            final Project project = getProject();
174            mkDir( m_destination );
175            final Javac javac = (Javac) getProject().createTask( "javac" );
176            javac.setTaskName( getTaskName() );
177            javac.setIncludeantruntime( false );
178            String lint = getProperty( "project.javac.lint", null );
179            if( null != lint )
180            {
181                javac.createCompilerArg().setValue( "-Xlint:" + lint );
182            }
183            
184            final Path srcDirPath = new Path( project );
185            srcDirPath.createPathElement().setLocation( m_source );
186            javac.setSrcdir( srcDirPath );
187            
188            final Path srcPath = new Path( project );
189            FileSet fileset = super.getImplicitFileSet();
190            fileset.setDir( m_source );
191            javac.setSourcepath( srcPath );
192            
193            javac.setDestdir( m_destination );
194            javac.setDeprecation( getDeprecationProperty() );
195            javac.setDebug( getDebugProperty() );
196            javac.setFork( getForkProperty() );
197            javac.setSource( getSourceProperty() );
198            javac.setTarget( getTargetProperty() );
199            javac.setClasspath( classpath );
200            javac.init();
201            javac.execute();
202            
203            copy( m_source, m_destination, false, "**/*.*", "**/*.java,**/package.html" );
204    
205        }
206        
207        private Path getClasspath()
208        {
209            if( null != m_classPath )
210            {
211                return m_classPath;
212            }
213            else if( null != m_classPathRef )
214            {
215                return (Path) getProject().getReference( m_classPathRef );
216            }
217            else
218            {
219                final String error = 
220                  "Missing 'classpathRef' or 'classpath' attribute.";
221                throw new BuildException( error, getLocation() );
222            }
223        }
224        
225        private boolean getDebugProperty()
226        {
227            return getBooleanProperty( DEBUG_KEY, DEBUG_VALUE );
228        }
229    
230        private boolean getDeprecationProperty()
231        {
232            return getBooleanProperty( DEPRECATION_KEY, DEPRECATION_VALUE );
233        }
234    
235        private boolean getForkProperty()
236        {
237            return getBooleanProperty( FORK_KEY, FORK_VALUE );
238        }
239    
240        private String getSourceProperty()
241        {
242            return getProperty( SOURCE_KEY, SOURCE_VALUE );
243        }
244    
245        private String getTargetProperty()
246        {
247            return getProperty( TARGET_KEY, TARGET_VALUE );
248        }
249    
250        private boolean getBooleanProperty( final String key, final boolean fallback )
251        {
252            String value = getContext().getProperty( key );
253            if( null == value )
254            {
255                return fallback;
256            }
257            else
258            {
259                return Project.toBoolean( value );
260            }
261        }
262        
263        private String getProperty( final String key, final String fallback )
264        {
265            String value = getContext().getProperty( key );
266            if( null == value )
267            {
268                return fallback;
269            }
270            else
271            {
272                return value;
273            }
274        }
275    
276        void mkDir( final File dir )
277        {
278            final Mkdir mkdir = (Mkdir) getProject().createTask( "mkdir" );
279            mkdir.setTaskName( getTaskName() );
280            mkdir.setDir( dir );
281            mkdir.init();
282            mkdir.execute();
283        }
284    
285        void copy(
286           final File src, final File destination, final boolean filtering, final String includes, final String excludes )
287        {
288            mkDir( destination );
289            final Copy copy = (Copy) getProject().createTask( "copy" );
290            copy.setTaskName( getTaskName() );
291            copy.setTodir( destination );
292            copy.setFiltering( filtering );
293            copy.setOverwrite( false );
294            copy.setPreserveLastModified( true );
295            final FileSet fileset = new FileSet();
296            fileset.setDir( src );
297            fileset.setIncludes( includes );
298            fileset.setExcludes( excludes );
299            copy.addFileset( fileset );
300            copy.init();
301            copy.execute();
302        }
303    
304       /**
305        * Get the project definition.
306        * @return the build context
307        */
308        protected Context getContext()
309        {
310            Context context = (Context) getProject().getReference( "project.context" );
311            if( null == context )
312            {
313                final String error = 
314                  "Missing project context reference.";
315                throw new BuildException( error );
316            }
317            return context;
318        }
319    
320    }